package com.muyu.vehicle.service.impl;

import java.util.*;

import com.muyu.vehicle.config.Config;
import com.muyu.vehicle.domain.vo.IndexVehicleData;
import com.muyu.vehicle.domain.vo.VehicleFenceVo;
import com.muyu.vehicle.domain.vo.VehicleIndexVo;
import com.muyu.vehicle.mapper.VehicleEsMapper;
import com.muyu.vehicle.process.SynchronizeVehicleFenceThread;
import com.muyu.vehicle.process.ThreadPool;
import com.vehicle.common.core.utils.DateUtils;
import com.vehicle.common.core.utils.IdUtils;
import com.vehicle.common.core.utils.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import com.muyu.vehicle.mapper.VehicleInfoMapper;
import com.muyu.vehicle.domain.VehicleInfo;
import com.muyu.vehicle.service.IVehicleInfoService;

/**
 * 车辆信息Service业务层处理
 *
 * @author muyu
 * @date 2021-09-04
 */
@Service
public class VehicleInfoServiceImpl implements IVehicleInfoService
{
    @Autowired
    private VehicleInfoMapper vehicleInfoMapper;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    VehicleEsMapper vehicleEsMapper;
    @Override
    public boolean createIndex() {
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(VehicleInfo.class);
        indexOperations.create();
        Document mapping = indexOperations.createMapping();
        return indexOperations.putMapping(mapping);
    }
    /**
     * 查询车辆信息
     *
     * @param id 车辆信息主键
     * @return 车辆信息
     */
    @Override
    public VehicleInfo selectVehicleInfoById(String id)
    {
        return vehicleInfoMapper.selectVehicleInfoById(id);
    }

    @Override
    public List<VehicleInfo> selectList(VehicleInfo vehicleInfo) {
        if(StringUtils.isNotEmpty(vehicleInfo.getVehicleVin())||StringUtils.isNotEmpty(vehicleInfo.getVehicleCode())||StringUtils.isNotEmpty(vehicleInfo.getVehicleMotor())||StringUtils.isNotEmpty(vehicleInfo.getVehicleMotorCode())||StringUtils.isNotEmpty(vehicleInfo.getVehicleBatteryCode())){
            NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            //模糊查询
            String fields = null;
            if(StringUtils.isNotEmpty(vehicleInfo.getVehicleVin())){
                boolQueryBuilder.must(
                        QueryBuilders.matchQuery("vehicleVin",vehicleInfo.getVehicleVin())
                );
                fields = "vehicleVin";
            }
            if(StringUtils.isNotEmpty(vehicleInfo.getVehicleCode())){
                boolQueryBuilder.must(
                        QueryBuilders.matchQuery("vehicleCode",vehicleInfo.getVehicleCode())
                );
                fields = "vehicleCode";
            }
            if(StringUtils.isNotEmpty(vehicleInfo.getVehicleMotor())){
                boolQueryBuilder.must(
                        QueryBuilders.matchQuery("vehicleMotor",vehicleInfo.getVehicleMotor())
                );
                fields = "vehicleMotor";
            }
            if(StringUtils.isNotEmpty(vehicleInfo.getVehicleMotorCode())){
                boolQueryBuilder.must(
                        QueryBuilders.matchQuery("vehicleMotorCode",vehicleInfo.getVehicleMotorCode())
                );
                fields = "vehicleMotorCode";
            }
            if(StringUtils.isNotEmpty(vehicleInfo.getVehicleBatteryCode())){
                boolQueryBuilder.must(
                        QueryBuilders.matchQuery("vehicleBatteryCode",vehicleInfo.getVehicleBatteryCode())
                );
                fields = "vehicleBatteryCode";
            }
            nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
            //高亮处理
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.field(fields)
                    .preTags("<fontcolor='red'>")
                    .postTags("</font>");
            nativeSearchQueryBuilder.withHighlightBuilder(highlightBuilder);
            SearchHits<VehicleInfo> search = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), VehicleInfo.class);
            long totalHits = search.getTotalHits();
            List<VehicleInfo> vehicleInfos = new ArrayList<>();
            if (totalHits>0){
                for (SearchHit<VehicleInfo> searchHit : search.getSearchHits()) {
                    VehicleInfo content = searchHit.getContent();
                    List<String> highlightField = searchHit.getHighlightField(fields);
                    if(highlightField.size()>0){
                        if(StringUtils.isNotEmpty(vehicleInfo.getVehicleVin())){
                            content.setVehicleVin(highlightField.get(0));
                        }
                        if(StringUtils.isNotEmpty(vehicleInfo.getVehicleCode())){
                            content.setVehicleCode(highlightField.get(0));
                        }
                        if(StringUtils.isNotEmpty(vehicleInfo.getVehicleMotor())){
                            content.setVehicleMotor(highlightField.get(0));
                        }
                        if(StringUtils.isNotEmpty(vehicleInfo.getVehicleMotorCode())){
                            content.setVehicleMotorCode(highlightField.get(0));
                        }
                        if(StringUtils.isNotEmpty(vehicleInfo.getVehicleBatteryCode())){
                            content.setVehicleBatteryCode(highlightField.get(0));
                        }
                    }
                    vehicleInfos.add(content);
                }
            }
            return vehicleInfos;
        }else {
            List<VehicleInfo> vehicleInfos = vehicleInfoMapper.selectVehicleInfoList(vehicleInfo);
            return vehicleInfos;
        }


    }

    /**
     * 查询车辆信息列表
     *
     * @param vehicleInfo 车辆信息
     * @return 车辆信息
     */
    @Override
    public List<VehicleInfo> selectVehicleInfoList(VehicleInfo vehicleInfo)
    {
        return vehicleInfoMapper.selectVehicleInfoList(vehicleInfo);
    }

    /**
     * 新增车辆信息
     *
     * @param vehicleInfo 车辆信息
     * @return 结果
     */
    @Override
    public int insertVehicleInfo(VehicleInfo vehicleInfo)
    {
        vehicleInfo.setCreateTime(DateUtils.getNowDate());
        vehicleInfo.setId(IdUtils.fastSimpleUUID());

        try {
            int i = vehicleInfoMapper.insertVehicleInfo(vehicleInfo);
            vehicleEsMapper.save(vehicleInfo);
            return i;
        }finally {
            ThreadPool.exeThread(new SynchronizeVehicleFenceThread(redisTemplate,this,vehicleInfo.getVehicleVin()));
        }
    }

    /**
     * 修改车辆信息
     *
     * @param vehicleInfo 车辆信息
     * @return 结果
     */
    @Override
    public int updateVehicleInfo(VehicleInfo vehicleInfo)
    {
        vehicleInfo.setUpdateTime(DateUtils.getNowDate());
        return vehicleInfoMapper.updateVehicleInfo(vehicleInfo);
    }

    /**
     * 批量删除车辆信息
     *
     * @param ids 需要删除的车辆信息主键
     * @return 结果
     */
    @Override
    public int deleteVehicleInfoByIds(String[] ids)
    {
        try {
            return vehicleInfoMapper.deleteVehicleInfoByIds(ids);
        }finally {
            HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();
            hashOperations.delete(Config.VEHICLE_FENCE_BIND , ids);
        }
    }

    /**
     * 删除车辆信息信息
     *
     * @param id 车辆信息主键
     * @return 结果
     */
    @Override
    public int deleteVehicleInfoById(String id)
    {
        return vehicleInfoMapper.deleteVehicleInfoById(id);
    }

    @Override
    public void updateVehicleStatusByVin(String vin, Integer status) {
        vehicleInfoMapper.updateVehicleStatusByVin(vin,status);
    }

    @Override
    public List<VehicleFenceVo> selectVehicleFence(String vin) {
        return vehicleInfoMapper.selectVehicleFence(vin);
    }

    @Override
    public VehicleIndexVo getIndexVehicleData() {
        VehicleIndexVo vehicleIndexVo = vehicleInfoMapper.selectIndexVehiceData();
        Set<String> keys = redisTemplate.keys(Config.VEHICLE_CURRENT_LOCATION+"*");
        ValueOperations<String, String> strOperations = redisTemplate.opsForValue();
        for (String key : keys) {
            String value = strOperations.get(key);
            IndexVehicleData indexVehicleData = new IndexVehicleData();
            indexVehicleData.setVin(key.replace(Config.VEHICLE_CURRENT_LOCATION,""));
            indexVehicleData.setPosition(value.split(","));
            vehicleIndexVo.setVehicleDataList(indexVehicleData);
        }
        return vehicleIndexVo;
    }
}
